import { jsPDF } from "jspdf";
import html2canvas from "html2canvas";

/**
 * 将多个ECharts图表导出为单个PDF文件
 * @param {Object[]} charts - 图表配置数组
 * @param {HTMLElement} charts[].dom - 图表的DOM元素
 * @param {string} charts[].title - 图表标题
 * @param {string} [fileName='charts_export'] - 导出的PDF文件名
 * @param {Object} [options] - 额外选项
 */
export async function exportMultiChartsToPDF(charts, fileName = "charts_export", options = {}) {
  try {
    // 默认选项
    const defaultOptions = {
      mainTitle: "图表导出报告",
      orientation: "portrait",
      pageWidth: 595,
      pageHeight: 842,
      margin: 50,
    };

    const finalOptions = { ...defaultOptions, ...options };

    // 创建PDF实例
    const pdf = new jsPDF({
      orientation: finalOptions.orientation,
      unit: "px",
      format: [finalOptions.pageWidth, finalOptions.pageHeight],
      compress: true,
      putOnlyUsedFonts: true,
    });

    // 由于字体问题，使用Canvas来渲染标题
    // 创建标题Canvas
    const headerCanvas = document.createElement("canvas");
    headerCanvas.width = finalOptions.pageWidth - 2 * finalOptions.margin;
    headerCanvas.height = 60;
    const headerCtx = headerCanvas.getContext("2d");

    // 绘制主标题
    headerCtx.fillStyle = "#ffffff";
    headerCtx.fillRect(0, 0, headerCanvas.width, headerCanvas.height);
    headerCtx.fillStyle = "#333333";
    headerCtx.font = "bold 20px Arial";
    headerCtx.textAlign = "center";
    headerCtx.fillText(finalOptions.mainTitle, headerCanvas.width / 2, 25);

    // 绘制时间
    headerCtx.font = "12px Arial";
    headerCtx.fillText(`生成时间: ${new Date().toLocaleString()}`, headerCanvas.width / 2, 50);

    // 添加标题到PDF
    const headerImgData = headerCanvas.toDataURL("image/png", 1.0);
    pdf.addImage(headerImgData, "PNG", finalOptions.margin, finalOptions.margin, headerCanvas.width, headerCanvas.height);

    let currentY = finalOptions.margin + headerCanvas.height + 20;
    let pageCount = 1;

    // 计算图表在PDF中的宽度（页面宽度的90%）
    const pdfContentWidth = finalOptions.pageWidth - 2 * finalOptions.margin;
    const chartWidth = pdfContentWidth * 0.9; // 设置为页面宽度的90%
    const leftMargin = finalOptions.margin + (pdfContentWidth - chartWidth) / 2; // 居中显示

    // 处理每个图表
    for (let i = 0; i < charts.length; i++) {
      const chart = charts[i];

      // 确保dom元素存在
      if (!chart.dom) {
        console.warn(`图表 ${i + 1} 的DOM元素不存在，已跳过`);
        continue;
      }

      // 临时处理：如果图表当前未显示，先临时显示它以便导出
      const originalDisplay = chart.dom.style.display;
      const originalVisibility = chart.dom.style.visibility;
      const originalPosition = chart.dom.style.position;
      const originalHeight = chart.dom.style.height;
      const originalWidth = chart.dom.style.width;

      // 临时修改图表样式以确保能够正确渲染
      if (originalDisplay === "none" || originalVisibility === "hidden") {
        chart.dom.style.display = "block";
        chart.dom.style.visibility = "visible";
        chart.dom.style.position = "absolute";
        chart.dom.style.left = "-9999px";
        chart.dom.style.top = "0";
        chart.dom.style.height = "500px"; // 给一个合理的高度
        chart.dom.style.width = "500px"; // 给一个合理的宽度

        // 如果图表使用ECharts，尝试重新渲染它
        if (chart.dom.querySelector("canvas") && chart.echart) {
          chart.echart.resize();
        }
      }

      // 创建图表标题Canvas
      const titleCanvas = document.createElement("canvas");
      titleCanvas.width = chartWidth;
      titleCanvas.height = 30;
      const titleCtx = titleCanvas.getContext("2d");

      // 绘制图表标题
      titleCtx.fillStyle = "#ffffff";
      titleCtx.fillRect(0, 0, titleCanvas.width, titleCanvas.height);
      titleCtx.fillStyle = "#333333";
      titleCtx.font = "bold 16px Arial";
      titleCtx.textAlign = "center";
      titleCtx.fillText(chart.title || `图表 ${i + 1}`, titleCanvas.width / 2, 20);

      // 使用html2canvas将图表转换为图片
      const canvas = await html2canvas(chart.dom, {
        scale: 2,
        useCORS: true,
        logging: true,
        backgroundColor: "#FFFFFF",
        allowTaint: true,
        foreignObjectRendering: false,
      });

      // 恢复图表原始样式
      if (originalDisplay === "none" || originalVisibility === "hidden") {
        chart.dom.style.display = originalDisplay;
        chart.dom.style.visibility = originalVisibility;
        chart.dom.style.position = originalPosition;
        chart.dom.style.height = originalHeight;
        chart.dom.style.width = originalWidth;
      }

      // 获取图片数据
      const imgData = canvas.toDataURL("image/png", 1.0);

      // 计算图片在PDF中的尺寸，保持宽高比
      const imgRatio = canvas.height / canvas.width;
      const imgWidth = chartWidth;
      const imgHeight = imgWidth * imgRatio;

      // 检查是否需要新页面
      if (currentY + titleCanvas.height + imgHeight + 30 > finalOptions.pageHeight - finalOptions.margin) {
        pdf.addPage();
        pageCount++;
        currentY = finalOptions.margin;
      }

      // 添加图表标题
      const titleImgData = titleCanvas.toDataURL("image/png", 1.0);
      pdf.addImage(titleImgData, "PNG", leftMargin, currentY, titleCanvas.width, titleCanvas.height);
      currentY += titleCanvas.height + 10;

      // 添加图表图片
      pdf.addImage(imgData, "PNG", leftMargin, currentY, imgWidth, imgHeight);
      currentY += imgHeight + 30;
    }

    // 添加页码 (也用canvas绘制)
    for (let i = 0; i < pageCount; i++) {
      pdf.setPage(i + 1);

      const footerCanvas = document.createElement("canvas");
      footerCanvas.width = finalOptions.pageWidth - 2 * finalOptions.margin;
      footerCanvas.height = 20;
      const footerCtx = footerCanvas.getContext("2d");

      footerCtx.fillStyle = "#ffffff";
      footerCtx.fillRect(0, 0, footerCanvas.width, footerCanvas.height);
      footerCtx.fillStyle = "#333333";
      footerCtx.font = "10px Arial";
      footerCtx.textAlign = "center";
      footerCtx.fillText(`第 ${i + 1} 页，共 ${pageCount} 页`, footerCanvas.width / 2, 10);

      const footerImgData = footerCanvas.toDataURL("image/png", 1.0);
      pdf.addImage(footerImgData, "PNG", finalOptions.margin, finalOptions.pageHeight - 30, footerCanvas.width, footerCanvas.height);
    }

    // 保存PDF文件
    pdf.save(`${fileName}.pdf`);
    return true;
  } catch (error) {
    console.error("导出多图表PDF失败:", error);
    throw new Error("导出PDF失败");
  }
}

/**
 * 将el-table-v2的数据导出为PDF
 * @param {Object} tableConfig - 表格配置
 * @param {Array} tableConfig.data - 表格数据源
 * @param {Array} tableConfig.columns - 表格列配置
 * @param {string} tableConfig.title - 表格标题
 * @param {string} [fileName='table_export'] - 导出的PDF文件名
 * @param {Object} [options] - 额外选项
 */
export async function exportTableToPDF(tableConfig, fileName = "table_export", options = {}) {
  try {
    // 默认选项
    const defaultOptions = {
      mainTitle: "表格导出报告",
      orientation: "portrait",
      pageWidth: 595,
      pageHeight: 842,
      margin: 50,
      rowsPerPage: 20,
      minFontSize: 9, // 最小字体大小
      maxRowHeight: 60, // 最大行高
      fontSize: {
        title: 12, // 主标题字体大小
        subtitle: 10, // 副标题字体大小
        header: 10, // 表头字体大小
        cell: 10, // 单元格字体大小
        footer: 10, // 页脚字体大小
      },
      quality: {
        scale: 3, // Canvas渲染缩放比例，提高精度
        imageQuality: 1.0, // 图像质量(0-1)
        pdfQuality: 1.0, // PDF压缩质量(0-1)
      },
    };

    const finalOptions = { ...defaultOptions, ...options };
    const { data, columns, title } = tableConfig;

    if (!data || !Array.isArray(data) || !columns || !Array.isArray(columns)) {
      throw new Error("表格数据或列配置无效");
    }

    // 创建PDF实例
    const pdf = new jsPDF({
      orientation: finalOptions.orientation,
      unit: "px",
      format: [finalOptions.pageWidth, finalOptions.pageHeight],
      compress: true,
      putOnlyUsedFonts: true,
      precision: 16, // 提高精度
      hotfixes: ["px_scaling"], // 修复缩放问题
    });

    // 计算内容区域尺寸
    const contentWidth = finalOptions.pageWidth - 2 * finalOptions.margin;
    const contentHeight = finalOptions.pageHeight - 2 * finalOptions.margin;

    // 处理表格标题和页眉
    const headerHeight = 80; // 页眉高度
    let currentY = finalOptions.margin;
    let pageCount = 0;

    // 计算表格尺寸
    const tableWidth = contentWidth * 0.98; // 增加表格宽度占比
    const cellPadding = 5; // 减少单元格内边距
    const headerRowHeight = 40;

    // 创建高清Canvas的辅助函数
    const createHDCanvas = (width, height) => {
      const canvas = document.createElement("canvas");
      const scale = finalOptions.quality.scale;
      canvas.width = width * scale;
      canvas.height = height * scale;
      const ctx = canvas.getContext("2d");
      ctx.scale(scale, scale);

      // 启用字体平滑和抗锯齿
      ctx.textRendering = "optimizeLegibility";
      ctx.imageSmoothingEnabled = true;
      ctx.imageSmoothingQuality = "high";

      return { canvas, ctx, scale };
    };

    // 计算列宽 - 优先使用columns中提供的width，如果没有则智能计算
    const calculateColumnWidths = () => {
      // 检查是否所有列都提供了width
      const hasAllWidths = columns.every((col) => col.width);

      // 如果所有列都提供了width，直接使用
      if (hasAllWidths) {
        // 计算总宽度
        const totalWidth = columns.reduce((sum, col) => sum + (parseFloat(col.width) || 0), 0);
        // 按比例缩放到tableWidth
        return columns.map((col) => ((parseFloat(col.width) || 0) / totalWidth) * tableWidth);
      }

      // 如果只有部分列提供了width
      const fixedWidthColumns = columns.filter((col) => col.width);
      const variableWidthColumns = columns.filter((col) => !col.width);

      if (fixedWidthColumns.length > 0 && variableWidthColumns.length > 0) {
        // 计算固定宽度列的总宽度
        const fixedTotalWidth = fixedWidthColumns.reduce((sum, col) => sum + (parseFloat(col.width) || 0), 0);

        // 计算固定宽度列在tableWidth中占据的总宽度
        const fixedTableWidth = (fixedTotalWidth / (fixedTotalWidth + variableWidthColumns.length)) * tableWidth;
        const variableTableWidth = tableWidth - fixedTableWidth;

        // 按比例缩放固定宽度列
        const scaledFixedWidths = fixedWidthColumns.map((col) => ((parseFloat(col.width) || 0) / fixedTotalWidth) * fixedTableWidth);

        // 可变宽度列平均分配
        const variableWidth = variableTableWidth / variableWidthColumns.length;

        // 按照原始顺序重组列宽数组
        return columns.map((col) => {
          if (col.width) {
            const index = fixedWidthColumns.findIndex((c) => c === col);
            return scaledFixedWidths[index];
          } else {
            return variableWidth;
          }
        });
      }

      // 如果没有任何宽度，使用智能计算
      // 1. 分析数据中每列的最大字符长度
      const colMaxLengths = columns.map((col, index) => {
        const key = col.key || col.field || `col${index}`;
        let maxLength = String(col.title || `列 ${index + 1}`).length;

        // 检查每行数据
        data.forEach((row) => {
          const cellValue = row[key] !== undefined ? String(row[key]) : "";
          maxLength = Math.max(maxLength, cellValue.length);
        });

        return maxLength;
      });

      // 2. 设置权重系数 - 根据列的重要性设置基础权重
      const colWeights = columns.map((col, index) => {
        // ID/序号列通常较窄，长文本列需要更多空间
        if (col.key === "id" || /^(序号|编号|index|code|no)$/i.test(col.title || "")) {
          return 0.6; // ID列权重低
        }

        if (/^(描述|备注|说明|description|remark|note|detail|content)$/i.test(col.title || "")) {
          return 2.0; // 描述列权重高
        }

        if (/^(名称|姓名|标题|题目|name|title)$/i.test(col.title || "")) {
          return 1.5; // 名称列权重较高
        }

        return 1.0; // 默认权重
      });

      // 3. 结合字符长度和权重计算初始宽度比例
      const totalLength = colMaxLengths.reduce((sum, len, idx) => sum + len * colWeights[idx], 0);
      const colWidthRatios = colMaxLengths.map((len, idx) => (len * colWeights[idx]) / totalLength);

      // 4. 应用最小宽度限制并重新计算
      const minWidthRatio = 0.05; // 最小列宽占比5%
      const adjustedRatios = colWidthRatios.map((ratio) => Math.max(ratio, minWidthRatio));

      // 5. 归一化比例
      const ratioSum = adjustedRatios.reduce((sum, ratio) => sum + ratio, 0);
      const normalizedRatios = adjustedRatios.map((ratio) => ratio / ratioSum);

      // 6. 计算最终的列宽
      return normalizedRatios.map((ratio) => tableWidth * ratio);
    };

    // 计算行高函数 - 根据单元格内容和列宽动态计算需要的行高
    const calculateRowHeight = (row, colWidths, ctx) => {
      let maxRowHeight = headerRowHeight; // 默认行高

      columns.forEach((column, colIndex) => {
        const key = column.key || column.field || `col${colIndex}`;
        const cellValue = row[key] !== undefined ? String(row[key]) : "";
        const availableWidth = colWidths[colIndex] - cellPadding * 2;

        if (cellValue && availableWidth > 0) {
          // 测量文本实际宽度
          const textWidth = ctx.measureText(cellValue).width;

          if (textWidth > availableWidth) {
            // 计算需要的行数
            const lines = Math.ceil(textWidth / availableWidth);
            const lineHeight = 16; // 单行高度
            const requiredHeight = lines * lineHeight + cellPadding * 2;
            maxRowHeight = Math.max(maxRowHeight, requiredHeight);
          }
        }
      });

      // 限制最大行高
      return Math.min(maxRowHeight, finalOptions.maxRowHeight);
    };

    // 绘制文本自动换行函数 - 改进文本渲染
    const drawWrappedText = (ctx, text, x, y, maxWidth, lineHeight) => {
      if (!text) return y;

      // 调整文本渲染设置，提高清晰度
      ctx.textBaseline = "middle";
      ctx.textRendering = "geometricPrecision";

      // 分词 - 为中文文本优化
      const words = text.split("");
      let line = "";
      let testLine = "";
      let testWidth = 0;
      let currentY = y + lineHeight / 2; // 调整为中线对齐

      for (let n = 0; n < words.length; n++) {
        testLine = line + words[n];
        testWidth = ctx.measureText(testLine).width;

        if (testWidth > maxWidth && n > 0) {
          // 应用字体平滑技术
          ctx.fillText(line, x, currentY);
          line = words[n];
          currentY += lineHeight;
        } else {
          line = testLine;
        }
      }

      ctx.fillText(line, x, currentY);
      return currentY + lineHeight / 2;
    };

    // 计算列宽
    const colWidths = calculateColumnWidths();

    // 计算总页数(根据数据行数和每页最大行数)
    const totalPages = Math.ceil(data.length / finalOptions.rowsPerPage);

    // 分页处理数据
    for (let pageIndex = 0; pageIndex < totalPages; pageIndex++) {
      // 添加新页(除第一页外)
      if (pageIndex > 0) {
        pdf.addPage();
      }
      pageCount++;
      currentY = finalOptions.margin;

      // 绘制页眉(包含标题和生成时间)
      const { canvas: headerCanvas, ctx: headerCtx } = createHDCanvas(contentWidth, headerHeight);

      // 绘制标题背景
      headerCtx.fillStyle = "#ffffff";
      headerCtx.fillRect(0, 0, contentWidth, headerHeight);

      // 绘制主标题
      headerCtx.fillStyle = "#333333";
      headerCtx.font = `bold ${finalOptions.fontSize.title}px Arial`;
      headerCtx.textAlign = "center";
      headerCtx.textBaseline = "middle"; // 改为中线对齐
      headerCtx.fillText(title || finalOptions.mainTitle, contentWidth / 2, 25);

      // 绘制表格标题
      headerCtx.font = `bold ${finalOptions.fontSize.subtitle}px Arial`;
      headerCtx.fillText(`${pageIndex + 1} / ${totalPages} 页`, contentWidth / 2, 50);

      // 绘制时间
      headerCtx.font = `${finalOptions.fontSize.subtitle}px Arial`;
      headerCtx.fillText(`生成时间: ${new Date().toLocaleString()}`, contentWidth / 2, 70);

      // 添加页眉到PDF
      const headerImgData = headerCanvas.toDataURL("image/png", finalOptions.quality.imageQuality);
      pdf.addImage(headerImgData, "PNG", finalOptions.margin, currentY, contentWidth, headerHeight);
      currentY += headerHeight + 10;

      // 计算当前页的数据起止索引
      const startIndex = pageIndex * finalOptions.rowsPerPage;
      const endIndex = Math.min(startIndex + finalOptions.rowsPerPage, data.length);
      const currentPageData = data.slice(startIndex, endIndex);

      // 预计算所有行高
      const { ctx: tempCtx } = createHDCanvas(1, 1);
      tempCtx.font = `${finalOptions.fontSize.cell}px Arial`;

      const rowHeights = currentPageData.map((row) => calculateRowHeight(row, colWidths, tempCtx));
      const totalTableHeight = headerRowHeight + rowHeights.reduce((sum, height) => sum + height, 0);

      // 创建表格Canvas - 使用高分辨率
      const { canvas: tableCanvas, ctx: tableCtx } = createHDCanvas(tableWidth, totalTableHeight);

      // 绘制表格背景
      tableCtx.fillStyle = "#ffffff";
      tableCtx.fillRect(0, 0, tableWidth, totalTableHeight);

      // 绘制表头
      tableCtx.fillStyle = "#f2f2f2";
      tableCtx.fillRect(0, 0, tableWidth, headerRowHeight);

      // 绘制表头文字
      tableCtx.fillStyle = "#333333";
      tableCtx.font = `bold ${finalOptions.fontSize.header}px Arial`;
      tableCtx.textAlign = "center";
      tableCtx.textBaseline = "middle";

      let currentX = 0;
      // 绘制列标题
      columns.forEach((column, colIndex) => {
        tableCtx.fillText(column.title || `列 ${colIndex + 1}`, currentX + colWidths[colIndex] / 2, headerRowHeight / 2);
        currentX += colWidths[colIndex];
      });

      // 绘制横向分隔线
      tableCtx.strokeStyle = "#e0e0e0";
      tableCtx.lineWidth = 1;
      tableCtx.beginPath();
      tableCtx.moveTo(0, headerRowHeight);
      tableCtx.lineTo(tableWidth, headerRowHeight);
      tableCtx.stroke();

      // 绘制数据行
      let currentRowY = headerRowHeight;
      currentPageData.forEach((row, rowIndex) => {
        const rowHeight = rowHeights[rowIndex];

        // 交替行背景色
        if (rowIndex % 2 === 1) {
          tableCtx.fillStyle = "#f9f9f9";
          tableCtx.fillRect(0, currentRowY, tableWidth, rowHeight);
        }

        // 绘制单元格数据
        tableCtx.fillStyle = "#333333";
        tableCtx.font = `${finalOptions.fontSize.cell}px Arial`;
        tableCtx.textAlign = "left"; // 文本左对齐
        tableCtx.textBaseline = "top"; // 文本顶部对齐

        let cellX = 0;
        columns.forEach((column, colIndex) => {
          // 获取单元格数据
          const key = column.key || column.field || `col${colIndex}`;
          const cellValue = row[key] !== undefined ? String(row[key]) : "";

          // 单元格内边距
          const cellInnerX = cellX + cellPadding;
          const cellInnerY = currentRowY + cellPadding;
          const cellInnerWidth = colWidths[colIndex] - cellPadding * 2;

          // 根据列类型决定对齐方式
          const isNumeric = /^([\d.,]+)$/.test(cellValue);
          if (isNumeric || /^(金额|价格|数量|数值|金额|费用|price|amount|sum|total|count|quantity)$/i.test(column.title || "")) {
            tableCtx.textAlign = "right";
            drawWrappedText(tableCtx, cellValue, cellInnerX + cellInnerWidth, cellInnerY, cellInnerWidth, 16);
            tableCtx.textAlign = "left";
          } else {
            drawWrappedText(tableCtx, cellValue, cellInnerX, cellInnerY, cellInnerWidth, 16);
          }

          cellX += colWidths[colIndex];
        });

        // 绘制行分隔线
        tableCtx.strokeStyle = "#e0e0e0";
        tableCtx.beginPath();
        tableCtx.moveTo(0, currentRowY + rowHeight);
        tableCtx.lineTo(tableWidth, currentRowY + rowHeight);
        tableCtx.stroke();

        currentRowY += rowHeight;
      });

      // 绘制垂直分隔线
      tableCtx.strokeStyle = "#e0e0e0";
      currentX = 0;
      for (let i = 0; i < columns.length; i++) {
        currentX += colWidths[i];
        if (i < columns.length - 1) {
          tableCtx.beginPath();
          tableCtx.moveTo(currentX, 0);
          tableCtx.lineTo(currentX, totalTableHeight);
          tableCtx.stroke();
        }
      }

      // 绘制表格边框
      tableCtx.strokeStyle = "#d0d0d0";
      tableCtx.lineWidth = 1;
      tableCtx.strokeRect(0, 0, tableWidth, totalTableHeight);

      // 将表格添加到PDF - 使用高质量设置
      const tableImgData = tableCanvas.toDataURL("image/png", finalOptions.quality.imageQuality);
      pdf.addImage(
        tableImgData,
        "PNG",
        finalOptions.margin + (contentWidth - tableWidth) / 2,
        currentY,
        tableWidth,
        totalTableHeight,
        undefined,
        "FAST",
        0
      );

      // 添加页码
      const { canvas: footerCanvas, ctx: footerCtx } = createHDCanvas(contentWidth, 20);

      footerCtx.fillStyle = "#ffffff";
      footerCtx.fillRect(0, 0, contentWidth, 20);
      footerCtx.fillStyle = "#333333";
      footerCtx.font = `${finalOptions.fontSize.footer}px Arial`;
      footerCtx.textAlign = "center";
      footerCtx.textBaseline = "middle";
      footerCtx.fillText(`第 ${pageIndex + 1} 页，共 ${totalPages} 页`, contentWidth / 2, 10);

      const footerImgData = footerCanvas.toDataURL("image/png", finalOptions.quality.imageQuality);
      pdf.addImage(footerImgData, "PNG", finalOptions.margin, finalOptions.pageHeight - 30, contentWidth, 20);
    }

    // 设置PDF输出质量
    if (finalOptions.quality.pdfQuality < 1) {
      pdf.setProperties({
        compression: true,
        compressPdf: true,
        quality: finalOptions.quality.pdfQuality,
      });
    }

    // 保存PDF文件
    pdf.save(`${fileName}.pdf`);
    return true;
  } catch (error) {
    console.error("导出表格PDF失败:", error);
    throw new Error("导出表格PDF失败");
  }
}

/**
 * 将ECharts图表和表格数据一起导出为PDF
 * @param {Object} config - 导出配置
 * @param {Object[]} config.charts - 图表配置数组
 * @param {HTMLElement} config.charts[].dom - 图表的DOM元素
 * @param {Object} config.charts[].echart - 图表实例(可选)
 * @param {string} config.charts[].title - 图表标题
 * @param {Object} config.tableConfig - 表格配置
 * @param {Array} config.tableConfig.data - 表格数据源
 * @param {Array} config.tableConfig.columns - 表格列配置
 * @param {string} config.tableConfig.title - 表格标题
 * @param {string} [fileName='report_export'] - 导出的PDF文件名
 * @param {Object} [options] - 额外选项
 */
export async function exportChartsAndTableToPDF(config, fileName = "report_export", options = {}) {
  try {
    const { charts, tableConfig } = config;

    if (!charts || !Array.isArray(charts) || charts.length === 0) {
      throw new Error("图表配置无效");
    }

    if (!tableConfig || !tableConfig.data || !Array.isArray(tableConfig.data) || !tableConfig.columns || !Array.isArray(tableConfig.columns)) {
      throw new Error("表格数据或列配置无效");
    }

    // 默认选项
    const defaultOptions = {
      mainTitle: "综合数据报告",
      orientation: "portrait",
      pageWidth: 595,
      pageHeight: 842,
      margin: 50,
      rowsPerPage: 20,
      minFontSize: 9,
      maxRowHeight: 60,
      fontSize: {
        title: 12,
        subtitle: 10,
        header: 10,
        cell: 10,
        footer: 10,
      },
      quality: {
        scale: 3, // Canvas渲染缩放比例，提高精度
        imageQuality: 1.0, // 图像质量(0-1)
        pdfQuality: 1.0, // PDF压缩质量(0-1)
      },
    };

    const finalOptions = { ...defaultOptions, ...options };

    // 创建PDF实例
    const pdf = new jsPDF({
      orientation: finalOptions.orientation,
      unit: "px",
      format: [finalOptions.pageWidth, finalOptions.pageHeight],
      compress: true,
      putOnlyUsedFonts: true,
      precision: 16,
      hotfixes: ["px_scaling"],
    });

    // 计算内容区域尺寸
    const contentWidth = finalOptions.pageWidth - 2 * finalOptions.margin;
    const contentHeight = finalOptions.pageHeight - 2 * finalOptions.margin;

    // 创建高清Canvas的辅助函数
    const createHDCanvas = (width, height) => {
      const canvas = document.createElement("canvas");
      const scale = finalOptions.quality.scale;
      canvas.width = width * scale;
      canvas.height = height * scale;
      const ctx = canvas.getContext("2d");
      ctx.scale(scale, scale);

      // 启用字体平滑和抗锯齿
      ctx.textRendering = "optimizeLegibility";
      ctx.imageSmoothingEnabled = true;
      ctx.imageSmoothingQuality = "high";

      return { canvas, ctx, scale };
    };

    // 处理表格标题和页眉的辅助函数
    const addHeaderToPDF = (title, pageIndex, totalPages, currentY) => {
      const headerHeight = 80;
      const { canvas: headerCanvas, ctx: headerCtx } = createHDCanvas(contentWidth, headerHeight);

      // 绘制标题背景
      headerCtx.fillStyle = "#ffffff";
      headerCtx.fillRect(0, 0, contentWidth, headerHeight);

      // 绘制主标题
      headerCtx.fillStyle = "#333333";
      headerCtx.font = `bold ${finalOptions.fontSize.title}px Arial`;
      headerCtx.textAlign = "center";
      headerCtx.textBaseline = "middle";
      headerCtx.fillText(title || finalOptions.mainTitle, contentWidth / 2, 25);

      // 绘制页码信息
      headerCtx.font = `bold ${finalOptions.fontSize.subtitle}px Arial`;
      headerCtx.fillText(`${pageIndex + 1} / ${totalPages} 页`, contentWidth / 2, 50);

      // 绘制时间
      headerCtx.font = `${finalOptions.fontSize.subtitle}px Arial`;
      headerCtx.fillText(`生成时间: ${new Date().toLocaleString()}`, contentWidth / 2, 70);

      // 添加页眉到PDF
      const headerImgData = headerCanvas.toDataURL("image/png", finalOptions.quality.imageQuality);
      pdf.addImage(headerImgData, "PNG", finalOptions.margin, currentY, contentWidth, headerHeight);

      return { headerHeight, headerImgData };
    };

    // 添加页脚的辅助函数
    const addFooterToPDF = (pageIndex, totalPages) => {
      const { canvas: footerCanvas, ctx: footerCtx } = createHDCanvas(contentWidth, 20);

      footerCtx.fillStyle = "#ffffff";
      footerCtx.fillRect(0, 0, contentWidth, 20);
      footerCtx.fillStyle = "#333333";
      footerCtx.font = `${finalOptions.fontSize.footer}px Arial`;
      footerCtx.textAlign = "center";
      footerCtx.textBaseline = "middle";
      footerCtx.fillText(`第 ${pageIndex + 1} 页，共 ${totalPages} 页`, contentWidth / 2, 10);

      const footerImgData = footerCanvas.toDataURL("image/png", finalOptions.quality.imageQuality);
      pdf.addImage(footerImgData, "PNG", finalOptions.margin, finalOptions.pageHeight - 30, contentWidth, 20);
    };

    // 第一部分: 处理ECharts图表
    let pageCount = 0;
    let pageIndex = 0;

    // 先处理所有图表
    for (let i = 0; i < charts.length; i++) {
      const chart = charts[i];

      // 确保dom元素存在
      if (!chart.dom) {
        console.warn(`图表 ${i + 1} 的DOM元素不存在，已跳过`);
        continue;
      }

      // 如果是新页面，先添加新页（除了第一页）
      if (pageIndex > 0) {
        pdf.addPage();
      }

      let currentY = finalOptions.margin;

      // 添加页眉
      const chartTitle = chart.title || `图表 ${i + 1}`;
      // 总页数 = 图表数量 + 表格页数
      const estimatedTablePages = Math.ceil(tableConfig.data.length / finalOptions.rowsPerPage);
      const totalPages = charts.length + estimatedTablePages;

      const { headerHeight } = addHeaderToPDF(chartTitle, pageIndex, totalPages, currentY);
      currentY += headerHeight + 20;

      // 临时处理：如果图表当前未显示，先临时显示它以便导出
      const originalDisplay = chart.dom.style.display;
      const originalVisibility = chart.dom.style.visibility;
      const originalPosition = chart.dom.style.position;
      const originalHeight = chart.dom.style.height;
      const originalWidth = chart.dom.style.width;

      // 临时修改图表样式以确保能够正确渲染
      if (originalDisplay === "none" || originalVisibility === "hidden") {
        chart.dom.style.display = "block";
        chart.dom.style.visibility = "visible";
        chart.dom.style.position = "absolute";
        chart.dom.style.left = "-9999px";
        chart.dom.style.top = "0";
        chart.dom.style.height = "500px";
        chart.dom.style.width = "500px";

        // 如果图表使用ECharts，尝试重新渲染它
        if (chart.dom.querySelector("canvas") && chart.echart) {
          chart.echart.resize();
        }
      }

      // 使用html2canvas将图表转换为图片
      const canvas = await html2canvas(chart.dom, {
        scale: finalOptions.quality.scale,
        useCORS: true,
        logging: false,
        backgroundColor: "#FFFFFF",
        allowTaint: true,
        foreignObjectRendering: false,
      });

      // 恢复图表原始样式
      if (originalDisplay === "none" || originalVisibility === "hidden") {
        chart.dom.style.display = originalDisplay;
        chart.dom.style.visibility = originalVisibility;
        chart.dom.style.position = originalPosition;
        chart.dom.style.height = originalHeight;
        chart.dom.style.width = originalWidth;
      }

      // 获取图片数据
      const imgData = canvas.toDataURL("image/png", finalOptions.quality.imageQuality);

      // 计算图片在PDF中的尺寸，保持宽高比
      const imgRatio = canvas.height / canvas.width;
      const maxWidth = contentWidth * 0.9;
      const imgWidth = maxWidth;
      const imgHeight = imgWidth * imgRatio;

      // 确保图表不会超出页面
      const maxHeight = finalOptions.pageHeight - currentY - finalOptions.margin - 40;
      let finalImgHeight = imgHeight;
      let finalImgWidth = imgWidth;

      if (imgHeight > maxHeight) {
        finalImgHeight = maxHeight;
        finalImgWidth = finalImgHeight / imgRatio;
      }

      // 添加图表图片，居中显示
      const leftMargin = finalOptions.margin + (contentWidth - finalImgWidth) / 2;
      pdf.addImage(imgData, "PNG", leftMargin, currentY, finalImgWidth, finalImgHeight);

      // 添加页脚
      addFooterToPDF(pageIndex, totalPages);

      pageIndex++;
      pageCount++;
    }

    // 第二部分: 处理表格数据
    // 保存表格所需的页面总数，用于更新页码
    const tableData = tableConfig.data;
    const columns = tableConfig.columns;
    const tableTitle = tableConfig.title || "数据表格";

    // 计算表格列宽 (复用exportTableToPDF中的逻辑)
    const calculateColumnWidths = () => {
      // 检查是否所有列都提供了width
      const hasAllWidths = columns.every((col) => col.width);
      const tableWidth = contentWidth * 0.98;

      // 如果所有列都提供了width，直接使用
      if (hasAllWidths) {
        // 计算总宽度
        const totalWidth = columns.reduce((sum, col) => sum + (parseFloat(col.width) || 0), 0);
        // 按比例缩放到tableWidth
        return columns.map((col) => ((parseFloat(col.width) || 0) / totalWidth) * tableWidth);
      }

      // 如果只有部分列提供了width
      const fixedWidthColumns = columns.filter((col) => col.width);
      const variableWidthColumns = columns.filter((col) => !col.width);

      if (fixedWidthColumns.length > 0 && variableWidthColumns.length > 0) {
        // 计算固定宽度列的总宽度
        const fixedTotalWidth = fixedWidthColumns.reduce((sum, col) => sum + (parseFloat(col.width) || 0), 0);

        // 计算固定宽度列在tableWidth中占据的总宽度
        const fixedTableWidth = (fixedTotalWidth / (fixedTotalWidth + variableWidthColumns.length)) * tableWidth;
        const variableTableWidth = tableWidth - fixedTableWidth;

        // 按比例缩放固定宽度列
        const scaledFixedWidths = fixedWidthColumns.map((col) => ((parseFloat(col.width) || 0) / fixedTotalWidth) * fixedTableWidth);

        // 可变宽度列平均分配
        const variableWidth = variableTableWidth / variableWidthColumns.length;

        // 按照原始顺序重组列宽数组
        return columns.map((col) => {
          if (col.width) {
            const index = fixedWidthColumns.findIndex((c) => c === col);
            return scaledFixedWidths[index];
          } else {
            return variableWidth;
          }
        });
      }

      // 如果没有任何宽度，使用均匀分配
      return columns.map(() => tableWidth / columns.length);
    };

    // 文本自动换行函数
    const drawWrappedText = (ctx, text, x, y, maxWidth, lineHeight) => {
      if (!text) return y;

      // 调整文本渲染设置，提高清晰度
      ctx.textBaseline = "middle";
      ctx.textRendering = "geometricPrecision";

      // 分词 - 为中文文本优化
      const words = text.split("");
      let line = "";
      let testLine = "";
      let testWidth = 0;
      let currentY = y + lineHeight / 2;

      for (let n = 0; n < words.length; n++) {
        testLine = line + words[n];
        testWidth = ctx.measureText(testLine).width;

        if (testWidth > maxWidth && n > 0) {
          ctx.fillText(line, x, currentY);
          line = words[n];
          currentY += lineHeight;
        } else {
          line = testLine;
        }
      }

      ctx.fillText(line, x, currentY);
      return currentY + lineHeight / 2;
    };

    // 计算行高函数
    const calculateRowHeight = (row, colWidths, ctx) => {
      const headerRowHeight = 40;
      const cellPadding = 5;
      let maxRowHeight = headerRowHeight;

      columns.forEach((column, colIndex) => {
        const key = column.key || column.field || `col${colIndex}`;
        const cellValue = row[key] !== undefined ? String(row[key]) : "";
        const availableWidth = colWidths[colIndex] - cellPadding * 2;

        if (cellValue && availableWidth > 0) {
          // 测量文本实际宽度
          const textWidth = ctx.measureText(cellValue).width;

          if (textWidth > availableWidth) {
            // 计算需要的行数
            const lines = Math.ceil(textWidth / availableWidth);
            const lineHeight = 16;
            const requiredHeight = lines * lineHeight + cellPadding * 2;
            maxRowHeight = Math.max(maxRowHeight, requiredHeight);
          }
        }
      });

      // 限制最大行高
      return Math.min(maxRowHeight, finalOptions.maxRowHeight);
    };

    const colWidths = calculateColumnWidths();
    const tableWidth = contentWidth * 0.98;
    const cellPadding = 5;
    const headerRowHeight = 40;

    // 计算表格需要的页数
    const tablePages = Math.ceil(tableData.length / finalOptions.rowsPerPage);

    // 更新总页数
    const finalTotalPages = pageCount + tablePages;

    // 处理表格数据分页
    for (let tablePageIndex = 0; tablePageIndex < tablePages; tablePageIndex++) {
      // 添加新页
      pdf.addPage();

      let currentY = finalOptions.margin;
      const actualPageIndex = pageCount + tablePageIndex;

      // 添加页眉
      const { headerHeight } = addHeaderToPDF(tableTitle, actualPageIndex, finalTotalPages, currentY);
      currentY += headerHeight + 10;

      // 计算当前页的数据
      const startIndex = tablePageIndex * finalOptions.rowsPerPage;
      const endIndex = Math.min(startIndex + finalOptions.rowsPerPage, tableData.length);
      const currentPageData = tableData.slice(startIndex, endIndex);

      // 预计算行高
      const { ctx: tempCtx } = createHDCanvas(1, 1);
      tempCtx.font = `${finalOptions.fontSize.cell}px Arial`;

      const rowHeights = currentPageData.map((row) => calculateRowHeight(row, colWidths, tempCtx));
      const totalTableHeight = headerRowHeight + rowHeights.reduce((sum, height) => sum + height, 0);

      // 创建表格Canvas
      const { canvas: tableCanvas, ctx: tableCtx } = createHDCanvas(tableWidth, totalTableHeight);

      // 绘制表格背景
      tableCtx.fillStyle = "#ffffff";
      tableCtx.fillRect(0, 0, tableWidth, totalTableHeight);

      // 绘制表头
      tableCtx.fillStyle = "#f2f2f2";
      tableCtx.fillRect(0, 0, tableWidth, headerRowHeight);

      // 绘制表头文字
      tableCtx.fillStyle = "#333333";
      tableCtx.font = `bold ${finalOptions.fontSize.header}px Arial`;
      tableCtx.textAlign = "center";
      tableCtx.textBaseline = "middle";

      let currentX = 0;
      // 绘制列标题
      columns.forEach((column, colIndex) => {
        tableCtx.fillText(column.title || `列 ${colIndex + 1}`, currentX + colWidths[colIndex] / 2, headerRowHeight / 2);
        currentX += colWidths[colIndex];
      });

      // 绘制横向分隔线
      tableCtx.strokeStyle = "#e0e0e0";
      tableCtx.lineWidth = 1;
      tableCtx.beginPath();
      tableCtx.moveTo(0, headerRowHeight);
      tableCtx.lineTo(tableWidth, headerRowHeight);
      tableCtx.stroke();

      // 绘制数据行
      let currentRowY = headerRowHeight;
      currentPageData.forEach((row, rowIndex) => {
        const rowHeight = rowHeights[rowIndex];

        // 交替行背景色
        if (rowIndex % 2 === 1) {
          tableCtx.fillStyle = "#f9f9f9";
          tableCtx.fillRect(0, currentRowY, tableWidth, rowHeight);
        }

        // 绘制单元格数据
        tableCtx.fillStyle = "#333333";
        tableCtx.font = `${finalOptions.fontSize.cell}px Arial`;
        tableCtx.textAlign = "left";
        tableCtx.textBaseline = "top";

        let cellX = 0;
        columns.forEach((column, colIndex) => {
          // 获取单元格数据
          const key = column.key || column.field || `col${colIndex}`;
          const cellValue = row[key] !== undefined ? String(row[key]) : "";

          // 单元格内边距
          const cellInnerX = cellX + cellPadding;
          const cellInnerY = currentRowY + cellPadding;
          const cellInnerWidth = colWidths[colIndex] - cellPadding * 2;

          // 根据列类型决定对齐方式
          const isNumeric = /^([\d.,]+)$/.test(cellValue);
          if (isNumeric || /^(金额|价格|数量|数值|金额|费用|price|amount|sum|total|count|quantity)$/i.test(column.title || "")) {
            tableCtx.textAlign = "right";
            drawWrappedText(tableCtx, cellValue, cellInnerX + cellInnerWidth, cellInnerY, cellInnerWidth, 16);
            tableCtx.textAlign = "left";
          } else {
            drawWrappedText(tableCtx, cellValue, cellInnerX, cellInnerY, cellInnerWidth, 16);
          }

          cellX += colWidths[colIndex];
        });

        // 绘制行分隔线
        tableCtx.strokeStyle = "#e0e0e0";
        tableCtx.beginPath();
        tableCtx.moveTo(0, currentRowY + rowHeight);
        tableCtx.lineTo(tableWidth, currentRowY + rowHeight);
        tableCtx.stroke();

        currentRowY += rowHeight;
      });

      // 绘制垂直分隔线
      tableCtx.strokeStyle = "#e0e0e0";
      currentX = 0;
      for (let i = 0; i < columns.length; i++) {
        currentX += colWidths[i];
        if (i < columns.length - 1) {
          tableCtx.beginPath();
          tableCtx.moveTo(currentX, 0);
          tableCtx.lineTo(currentX, totalTableHeight);
          tableCtx.stroke();
        }
      }

      // 绘制表格边框
      tableCtx.strokeStyle = "#d0d0d0";
      tableCtx.lineWidth = 1;
      tableCtx.strokeRect(0, 0, tableWidth, totalTableHeight);

      // 将表格添加到PDF
      const tableImgData = tableCanvas.toDataURL("image/png", finalOptions.quality.imageQuality);
      pdf.addImage(
        tableImgData,
        "PNG",
        finalOptions.margin + (contentWidth - tableWidth) / 2,
        currentY,
        tableWidth,
        totalTableHeight,
        undefined,
        "FAST",
        0
      );

      // 添加页脚
      addFooterToPDF(actualPageIndex, finalTotalPages);
    }

    // 设置PDF输出质量
    if (finalOptions.quality.pdfQuality < 1) {
      pdf.setProperties({
        compression: true,
        compressPdf: true,
        quality: finalOptions.quality.pdfQuality,
      });
    }

    // 保存PDF
    pdf.save(`${fileName}.pdf`);
    return true;
  } catch (error) {
    console.error("导出图表和表格PDF失败:", error);
    throw new Error("导出PDF失败: " + error.message);
  }
}
